home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
emacs
/
emacs1857
/
src_d2.zoo
/
source
/
syntax.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-02
|
30KB
|
1,132 lines
/* GNU Emacs routines to deal with syntax tables; also word and list parsing.
Copyright (C) 1985, 1987, 1990 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#include <ctype.h>
#include "lisp.h"
#include "commands.h"
#include "buffer.h"
#include "syntax.h"
Lisp_Object Qsyntax_table_p;
DEFUN ("syntax-table-p", Fsyntax_table_p, Ssyntax_table_p, 1, 1, 0,
"Return t if ARG is a syntax table.\n\
Any vector of 256 elements will do.")
(obj)
Lisp_Object obj;
{
if (XTYPE (obj) == Lisp_Vector && XVECTOR (obj)->size == 0400)
return Qt;
return Qnil;
}
Lisp_Object
check_syntax_table (obj)
Lisp_Object obj;
{
register Lisp_Object tem;
while (tem = Fsyntax_table_p (obj),
NULL (tem))
obj = wrong_type_argument (Qsyntax_table_p, obj, 0);
return obj;
}
DEFUN ("syntax-table", Fsyntax_table, Ssyntax_table, 0, 0, 0,
"Return the current syntax table.\n\
This is the one specified by the current buffer.")
()
{
return current_buffer->syntax_table;
}
DEFUN ("standard-syntax-table", Fstandard_syntax_table,
Sstandard_syntax_table, 0, 0, 0,
"Return the standard syntax table.\n\
This is the one used for new buffers.")
()
{
return Vstandard_syntax_table;
}
DEFUN ("copy-syntax-table", Fcopy_syntax_table, Scopy_syntax_table, 0, 1, 0,
"Construct a new syntax table and return it.\n\
It is a copy of the TABLE, which defaults to the standard syntax table.")
(table)
Lisp_Object table;
{
Lisp_Object size, val;
XFASTINT (size) = 0400;
XFASTINT (val) = 0;
val = Fmake_vector (size, val);
if (!NULL (table))
table = check_syntax_table (table);
else if (NULL (Vstandard_syntax_table))
/* Can only be null during initialization */
return val;
else table = Vstandard_syntax_table;
bcopy (XVECTOR (table)->contents,
XVECTOR (val)->contents, 0400 * sizeof (Lisp_Object));
return val;
}
DEFUN ("set-syntax-table", Fset_syntax_table, Sset_syntax_table, 1, 1, 0,
"Select a new syntax table for the current buffer.\n\
One argument, a syntax table.")
(table)
Lisp_Object table;
{
table = check_syntax_table (table);
current_buffer->syntax_table = table;
/* Indicate that this buffer now has a specified syntax table. */
current_buffer->local_var_flags |= buffer_local_flags.syntax_table;
return table;
}
/* Convert a letter which signifies a syntax code
into the code it signifies.
This is used by modify-syntax-entry, and other things. */
char syntax_spec_code[0400] =
{ 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
(char) Swhitespace, 0377, (char) Sstring, 0377,
(char) Smath, 0377, 0377, (char) Squote,
(char) Sopen, (char) Sclose, 0377, 0377,
0377, (char) Swhitespace, (char) Spunct, (char) Scharquote,
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
0377, 0377, 0377, 0377,
(char) Scomment, 0377, (char) Sendcomment, 0377,
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, /* @, A, ... */
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword,
0377, 0377, 0377, 0377, (char) Sescape, 0377, 0377, (char) Ssymbol,
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, /* `, a, ... */
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword,
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377
};
/* Indexed by syntax code, give the letter that describes it. */
char syntax_code_spec[13] =
{
' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>'
};
DEFUN ("char-syntax", Fchar_syntax, Schar_syntax, 1, 1, 0,
"Return the syntax code of CHAR, described by a character.\n\
For example, if CHAR is a word constituent, ?w is returned.\n\
The characters that correspond to various syntax codes\n\
are listed in the documentation of modify-syntax-entry.")
(ch)
Lisp_Object ch;
{
CHECK_NUMBER (ch, 0);
return make_number (syntax_code_spec[(int) SYNTAX (0xFF & XINT (ch))]);
}
/* This comment supplies the doc string for modify-syntax-entry,
for make-docfile to see. We cannot put this in the real DEFUN
due to limits in the Unix cpp.
DEFUN ("modify-syntax-entry", foo, bar, 0, 0, 0,
"Set syntax for character CHAR according to string S.\n\
The syntax is changed only for table TABLE, which defaults to\n\
the current buffer's syntax table.\n\
The first character of S should be one of the following:\n\
Space whitespace syntax. w word constituent.\n\
_ symbol constituent. . punctuation.\n\
( open-parenthesis. ) close-parenthesis.\n\
\" string quote. \\ character-quote.\n\
$ paired delimiter. ' expression prefix operator.\n\
< comment starter. > comment ender.\n\
Only single-character comment start and end sequences are represented thus.\n\
Two-character sequences are represented as described below.\n\
The second character of S is the matching parenthesis,\n\
used only if the first character is ( or ).\n\
Any additional characters are flags.\n\
Defined flags are the characters 1, 2, 3 and 4.\n\
1 means C is the start of a two-char comment start sequence.\n\
2 means C is the second character of such a sequence.\n\
3 means C is the start of a two-char comment end sequence.\n\
4 means C is the second character of such a sequence.")
*/
DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3,
/* I really don't know why this is interactive
help-form should at least be made useful whilst reading the second arg
*/
"cSet syntax for character: \nsSet syntax for %s to: ",
0 /* See immediately above */)
(c, newentry, syntax_table)
Lisp_Object c, newentry, syntax_table;
{
register unsigned char *p, match;
register enum syntaxcode code;
Lisp_Object val;
CHECK_NUMBER (c, 0);
CHECK_STRING (newentry, 1);
if (NULL (syntax_table))
syntax_table = current_buffer->syntax_table;
else
syntax_table = check_syntax_table (syntax_table);
p = XSTRING (newentry)->data;
code = (enum syntaxcode) syntax_spec_code[*p++];
if (((int) code & 0377) == 0377)
error ("invalid syntax description letter: %c", c);
match = *p;
if (match) p++;
if (match == ' ') match = 0;
XFASTINT (val) = (match << 8) + (int) code;
while (*p)
switch (*p++)
{
case '1':
XFASTINT (val) |= 1 << 16;
break;
case '2':
XFASTINT (val) |= 1 << 17;
break;
case '3':
XFASTINT (val) |= 1 << 18;
break;
case '4':
XFASTINT (val) |= 1 << 19;
break;
}
XVECTOR (syntax_table)->contents[0xFF & XINT (c)] = val;
return Qnil;
}
/* Dump syntax table to buffer in human-readable format */
describe_syntax (value)
Lisp_Object value;
{
register enum syntaxcode code;
char desc, match, start1, start2, end1, end2;
char str[2];
Findent_to (make_number (16), make_number (1));
if (XTYPE (value) != Lisp_Int)
{
InsStr ("invalid");
return;
}
code = (enum syntaxcode) (XINT (value) & 0377);
match = (XINT (value) >> 8) & 0377;
start1 = (XINT (value) >> 16) & 1;
start2 = (XINT (value) >> 17) & 1;
end1 = (XINT (value) >> 18) & 1;
end2 = (XINT (value) >> 19) & 1;
if ((int) code < 0 || (int) code >= (int) Smax)
{
InsStr ("invalid");
return;
}
desc = syntax_code_spec[(int) code];
str[0] =